package cn.myframe.task;

import cn.myframe.dto.RdStockDto;
import cn.myframe.dto.RealTimeDto;
import cn.myframe.dto.StockBaseDto;
import cn.myframe.redis.RedisService;
import cn.myframe.util.Variance;
import cn.myframe.ws.WebSocketServer;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Author: ynz
 * @Date: 2019/3/19/019 18:45
 * @Version 1.0
 */
@Slf4j
@Component
public class RealTimeTrading {

    static List<StockBaseDto> stockBaseDtoList = new ArrayList<>();

    private final static String STOCK_KEY = "STOCK_LIST";

    private final static String STOCK_BASE = "STOCK:BASE";

    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(4,10,20,TimeUnit.SECONDS,new ArrayBlockingQueue(300));

    Map<String,RealTimeDto> map = new HashMap<>();

    List<String> stocksList = new ArrayList<>();

   String url = "http://qt.gtimg.cn/q=";

    private final static String RD_PRICE = "RD:PRICE";

    private final static String RD_ENTRUST = "RD:ENTRUST";

    private final static String RD_VOLUME = "RD:VOLUME";

    List<String> listR = new ArrayList<String>();

    @Autowired
    WebSocketServer webSocketServer;

    @Autowired
    RedisService redisService;

    @Autowired
    RestTemplate restTemplate;

    @PostConstruct
    public void init(){
        List<Object> list = redisService.getList(STOCK_KEY);
        List<Object> tempList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            if((i!=0 && i%200 == 0) || list.size()-1 == i){
                String  stockCodeStr = StringUtils.join(tempList.toArray(),",");
                stocksList.add(stockCodeStr);
                tempList.clear();
            }
            tempList.add(list.get(i));
        }
       new Thread(()->{
           trading();
        }).start();

        new Thread(()->{
            while (true){
                try {
                    String str = "";
                    for (int i = 0; i < listR.size(); i++) {
                        str = listR.get(i)+","+str;
                    }
                    System.out.println(str);
                    Thread.sleep(3000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }).start();



    }

    public void trading(){
        while (true){
            try{
                long time = System.currentTimeMillis();
                for(String stocks : stocksList){
                    Runnable runnable = ()->{
                        String response = restTemplate.getForObject(url+stocks , String.class);
                        DealTradData(response);
                    };
                    threadPoolExecutor.execute(runnable);
                }

                while(threadPoolExecutor.getActiveCount() != 0){

                }
                calTrend();
                log.info("耗时:{}",System.currentTimeMillis()-time);
            }catch (Exception e){

                e.printStackTrace();
            }
        }

    }

    /**
     * 处理返回的交易数据
     * @param response
     */
    public void DealTradData(String response){
        String[] stockDatas = response.split(";");
        for(String stockData : stockDatas){
            String[] datas = stockData.split("~");
            if(datas.length>32){
                if(!map.containsKey(datas[2])){
                    String stockCode = datas[2].startsWith("6")?"sh"+datas[2]:"sz"+datas[2];
                    RealTimeDto realTimeDto = new RealTimeDto();
                   // Object obj = redisService.hmGet(STOCK_BASE,stockCode);
                   /* if(obj != null){
                       // StockBaseDto baseDto = JSON.parseObject(redisService.hmGet(STOCK_BASE,stockCode).toString(),StockBaseDto.class);
                        realTimeDto.setYVolume(baseDto.getVolume())
                                .setStockCode(datas[2]);
                    }*/
                    realTimeDto.setStockCode(stockCode);
                    map.put(datas[2],realTimeDto);
                }
                RealTimeDto realTimeDto = map.get(datas[2]);
                realTimeDto.addQueue(Double.parseDouble(datas[32]))               //涨跌%
                        .addBuy(datas[10],datas[12],datas[14],datas[16],datas[18])//买单委托
                        .addSale(datas[20],datas[22],datas[24],datas[26],datas[28])//卖单委托
                        .setVolume((int)Double.parseDouble(datas[6]));
            }

        }
    }


    /**
     * 计算趋势
     */
    public void calTrend(){
        try {
            for(Map.Entry<String,RealTimeDto> dto : map.entrySet()){
                RealTimeDto realTimeDto = dto.getValue();
                double trend_1 = Variance.Variance(realTimeDto.getQueue_1().convertArray(Double.class));
                double trend_5 = Variance.Variance(realTimeDto.getQueue_5().convertArray(Double.class));
                double trend_10 =  Variance.Variance(realTimeDto.getQueue_10().convertArray(Double.class));
                double trend_30 =  Variance.Variance(realTimeDto.getQueue_30().convertArray(Double.class));
                if(trend_1>1.2||trend_5>1.2||trend_10>1.2||trend_30>1.2){
                    redisService.add(RD_PRICE,realTimeDto.getStockCode());
                    if(!listR.contains(realTimeDto.getStockCode())){
                        listR.add(realTimeDto.getStockCode());

                        String url = " http://image.sinajs.cn/newchart/min/n/Code.gif";
                        RdStockDto rdStockDto = new RdStockDto();
                        url = url.replaceAll("Code",realTimeDto.getStockCode());
                        rdStockDto.setStockCode(realTimeDto.getStockCode()).setUrl(url);
                        webSocketServer.sendInfo(JSON.toJSONString(rdStockDto));

                    }

                }

              /*  if(realTimeDto.getVolume()>realTimeDto.getYVolume()*0.8){
                    GregorianCalendar ca = new GregorianCalendar();
                    if(ca.get(GregorianCalendar.AM_PM) == 1){
                        redisService.add(RD_VOLUME,realTimeDto.getStockCode());
                    }
                }*/

                int buyMax = Collections.max(Arrays.asList(realTimeDto.getBuyArray()));
                int saleMax = Collections.max(Arrays.asList(realTimeDto.getSaleArray()));
                if(buyMax>saleMax*10){
                   /* redisService.add(RD_ENTRUST,realTimeDto.getStockCode());*/
                }

            }
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }









}
